#include "track.h"
#include "pattern.h"
#include "songitem.h"
#include "event.h"
using namespace std;

Track::Track()
: m_oldNote(Event::NoNote) {
}

Track::~Track() {
     for (size_t i=0; i<m_patterns.size(); i++) {
	  if (m_patterns[i])
	       delete m_patterns[i];
     }
     for (size_t i=0; i<m_songItems.size(); i++) {
	  if (m_songItems[i])
	       delete m_songItems[i];
     }
}

void Track::addPattern(Pattern *pPattern) {
     m_patterns.push_back(pPattern);
     pPattern->setNumber(m_patterns.size()-1);
}

void Track::removePattern(Pattern *pPattern) {
     bool found = false;
     Pattern *pPat = 0;
     for (vector<Pattern *>::iterator iter=m_patterns.begin(); 
	  iter!=m_patterns.end(); iter++) {

	  pPat = *iter;
	  if (!found) {
               if (pPat == pPattern) {
		    m_patterns.erase(iter);
		    found = true;
	       }
	  } else {
	       // decrease numbers after deleted one
	       pPat->setNumber(pPat->number() - 1);
	  }
     }
}

void Track::removePatternAt(int i) {
     if (!(size_t)i<m_patterns.size())
	  return;
     m_patterns.erase(m_patterns.begin()+i);
     for (size_t j=i; j<m_patterns.size(); j++) {
	  m_patterns.at(j)->setNumber(m_patterns.at(j)->number() - 1);
     }
}

Pattern *Track::patternAt(int i) {
     if ((size_t)i<m_patterns.size())
	  return m_patterns.at(i);
     return 0;
}

int Track::patternCount() {
     return (int)m_patterns.size();
}

void Track::setPatternCount(int count) {
     Pattern *pPat = NULL;
     while (count < patternCount()) {
	  pPat = m_patterns[patternCount() - 1];
	  m_patterns.pop_back();
	  if (pPat)
	       delete pPat;
     }
     while (count > patternCount()) {
	  m_patterns.push_back(new Pattern("", patternCount(), 
					   m_patterns[patternCount() - 1]->length()));
     }
}

void Track::addSongItem(SongItem *pSongItem) {
     m_songItems.push_back(pSongItem);
}

void Track::removeSongItem(SongItem *pSongItem) {
     for (vector<SongItem *>::iterator iter=m_songItems.begin(); 
	  iter!=m_songItems.end(); iter++) {
	  if (*iter == pSongItem)
	       m_songItems.erase(iter);
     }
}

void Track::removeSongItemAt(int i) {
     if ((size_t)i<m_songItems.size())
	  m_songItems.erase(m_songItems.begin()+i);
}

SongItem *Track::songItemAt(int i) {
     if ((size_t)i<m_songItems.size())
	  return m_songItems.at(i);
     return 0;
}

int Track::songItemCount() {
     return (int)m_songItems.size();
}

void Track::setSongItemCount(int count) {
     SongItem *pItem = NULL;
     while (count < songItemCount()) {
	  pItem = m_songItems[songItemCount() - 1];
	  m_songItems.pop_back();
	  if (pItem)
	       delete pItem;
     }
     while (count > songItemCount())
	  m_songItems.push_back(new SongItem(NULL, songItemCount() - 1));
}

int Track::oldNote() {
     return m_oldNote;
}

void Track::setOldNote(int oldNote) {
     m_oldNote = oldNote;
}

const string &Track::name() {
     return m_name;
}

void Track::setName(const string &name) {
     m_name = name;
}
